#!/bin/bash

# JDK安装脚本
# 自动下载并安装指定版本的JDK，并创建软链接

set -euo pipefail  # 遇到错误立即退出，使用未定义变量时报错，管道失败时报错

# 定义颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查命令是否存在
check_command() {
    if ! command -v "$1" &> /dev/null; then
        log_error "命令 '$1' 未找到，请先安装"
        case "$1" in
            "curl")
                log_info "在Ubuntu/Debian上安装: sudo apt-get install curl"
                log_info "在CentOS/RHEL上安装: sudo yum install curl"
                ;;
            "wget")
                log_info "在Ubuntu/Debian上安装: sudo apt-get install wget"
                log_info "在CentOS/RHEL上安装: sudo yum install wget"
                ;;
            "tar")
                log_info "tar通常是系统自带的，如果缺失请检查系统完整性"
                ;;
        esac
        exit 1
    fi
}

# 检查是否具有sudo权限
check_sudo() {
    if ! sudo -n true 2>/dev/null; then
        log_error "需要sudo权限来执行此脚本"
        log_info "请使用: sudo $0 或确保当前用户具有sudo权限"
        exit 1
    fi
}

# 从文件名提取JDK版本信息
extract_jdk_version() {
    local filename="$1"
    # 匹配模式: OpenJDK*U-jdk_x64_linux_hotspot_版本号_构建号.tar.gz
    echo "$filename" | sed -n 's/.*OpenJDK[0-9]*U-jdk_x64_linux_hotspot_\([0-9._]*\)\.tar\.gz$/\1/p'
}

# 检查本地是否已安装相同版本的JDK
check_local_jdk_version() {
    local expected_version="$1"
    local extract_dir="$2"
    
    # 检查解压目录是否存在
    if [ ! -d "/usr/local/java/$extract_dir" ]; then
        return 1  # 目录不存在，需要安装
    fi
    
    # 检查bin目录下的java可执行文件
    local java_bin="/usr/local/java/$extract_dir/bin/java"
    if [ ! -f "$java_bin" ]; then
        return 1  # java可执行文件不存在，需要安装
    fi
    
    # 获取已安装JDK的版本信息
    local installed_version=$("$java_bin" -version 2>&1 | head -n 1 | sed 's/.*version "\([0-9._]*\)".*/\1/')
    
    # 获取期望的版本（从文件名提取）
    local expected_short_version=$(echo "$expected_version" | cut -d'_' -f1)
    local installed_short_version=$(echo "$installed_version" | cut -d'_' -f1)
    
    if [ "$expected_short_version" = "$installed_short_version" ]; then
        log_info "已安装相同版本的JDK: $installed_version"
        return 0  # 版本相同，跳过安装
    else
        log_info "版本不同，需要更新: 已安装 $installed_version, 期望 $expected_short_version"
        return 1  # 版本不同，需要安装
    fi
}

# 获取指定JDK版本的最新下载链接
get_jdk_download_url() {
    local version="$1"
    local mirror_url="https://mirrors.tuna.tsinghua.edu.cn/Adoptium/${version}/jdk/x64/linux/"
    
    log_info "正在获取JDK ${version} 的下载链接..."
    
    # 获取网页HTML源码
    local html_content=$(curl -s "$mirror_url")
    
    # 检查是否获取成功
    if [ -z "$html_content" ]; then
        log_error "无法从镜像站获取内容: $mirror_url"
        log_info "可能的原因:"
        log_info "1. 网络连接问题，请检查网络连接"
        log_info "2. 镜像站暂时不可用"
        log_info "3. 该JDK版本可能不存在或路径已更改"
        log_info "请手动访问 $mirror_url 确认可用性"
        return 1
    fi
    
    # 从HTML中提取最新的tar.gz文件下载链接
    # 使用sed提取href属性中的链接，然后过滤出有效的下载链接，并按时间排序取最新的
    local download_url=$(echo "$html_content" | sed -n 's/.*href="\([^"]*\)".*/\1/p' | grep -E "\.tar\.gz$" | sort -r | head -n 1)
    
    # 检查是否找到文件
    if [ -z "$download_url" ]; then
        log_error "未找到JDK ${version} 的可下载文件"
        log_info "可能的原因:"
        log_info "1. 该版本的JDK可能尚未发布或已下架"
        log_info "2. 文件命名格式可能已更改"
        log_info "3. 请访问 $mirror_url "
        return 1
    fi
    
    # 确保URL是绝对路径
    if [[ "$download_url" == /* ]]; then
        # 如果URL是绝对路径（以/开头）
        echo "https://mirrors.tuna.tsinghua.edu.cn${download_url}"
    elif [[ "$download_url" =~ ^http ]]; then
        # 如果已经是完整URL
        echo "$download_url"
    else
        # 相对路径
        echo "${mirror_url}${download_url}"
    fi
}

# 下载并安装JDK
install_jdk() {
    local version="$1"
    local link_name="$2"
    
    log_info "开始安装JDK ${version}..."
    
    # 获取下载链接
    local download_url=$(get_jdk_download_url "$version")
    if [ $? -ne 0 ]; then
        return 1
    fi
    
    log_info "下载地址: $download_url"
    
    # 提取文件名
    local filename=$(basename "$download_url")
    local extract_dir=$(echo "$filename" | sed 's/\.tar\.gz$//')
    local file_version=$(extract_jdk_version "$filename")
    
    # 检查是否已安装相同版本
    if check_local_jdk_version "$file_version" "$extract_dir"; then
        log_success "JDK ${version} 已安装最新版本，跳过安装"
        return 0
    fi
    
    # 创建安装目录
    sudo mkdir -p /usr/local/java
    
    # 下载文件
    log_info "正在下载JDK ${version}..."
    if ! sudo wget -q --show-progress -O "/usr/local/java/$filename" "$download_url"; then
        log_error "下载JDK ${version} 失败"
        log_info "可能的原因:"
        log_info "1. 网络连接不稳定"
        log_info "2. 磁盘空间不足"
        log_info "3. 下载链接已失效"
        log_info "4. 权限不足（需要sudo权限）"
        log_info "请检查网络连接和磁盘空间后重试"
        return 1
    fi
    
    # 检查下载文件是否完整
    if [ ! -s "/usr/local/java/$filename" ]; then
        log_error "下载的文件为空或损坏: /usr/local/java/$filename"
        sudo rm -f "/usr/local/java/$filename"
        return 1
    fi
    
    # 清理旧版本（如果存在）
    if [ -d "/usr/local/java/$extract_dir" ]; then
        log_info "清理旧版本: /usr/local/java/$extract_dir"
        sudo rm -rf "/usr/local/java/$extract_dir"
    fi
    
    # 解压文件
    log_info "正在解压JDK ${version}..."
    if ! sudo tar -xzf "/usr/local/java/$filename" -C /usr/local/java/; then
        log_error "解压JDK ${version} 失败"
        log_info "可能的原因:"
        log_info "1. 下载的文件不完整或损坏"
        log_info "2. tar版本不兼容"
        log_info "3. 磁盘空间不足"
        log_info "请删除损坏的文件后重新运行脚本: sudo rm /usr/local/java/$filename"
        return 1
    fi
    
    # 创建软链接目录
    sudo mkdir -p /usr/lib64/jvm
    
    # 删除旧的软链接（如果存在）
    sudo rm -f "/usr/lib64/jvm/$link_name"
    
    # 创建新的软链接
    log_info "创建软链接 /usr/lib64/jvm/$link_name -> /usr/local/java/$extract_dir"
    sudo ln -sf "/usr/local/java/$extract_dir" "/usr/lib64/jvm/$link_name"
    
    # 更改文件权限
    sudo chown -R $USER: /usr/local/java/"$extract_dir"
    
    log_success "JDK ${version} 安装完成"
}

# 显示已安装的JDK信息
show_installed_jdks() {
    log_info "已安装的JDK软链接:"
    if [ -d "/usr/lib64/jvm" ]; then
        ls -la /usr/lib64/jvm/ 2>/dev/null || echo "无软链接"
    else
        echo "目录 /usr/lib64/jvm 不存在"
    fi
    
    log_info "已下载的JDK文件:"
    if [ -d "/usr/local/java" ]; then
        ls -la /usr/local/java/ 2>/dev/null || echo "无文件"
    else
        echo "目录 /usr/local/java 不存在"
    fi
}

# 主函数
main() {
    log_info "开始JDK安装过程..."
    log_info "当前工作目录: $(pwd)"
    log_info "用户: $(whoami)"
    echo ""
    
    # 检查sudo权限
    check_sudo
    
    # 创建安装目录
    log_info "创建安装目录 /usr/local/java..."
    sudo mkdir -p /usr/local/java
    
    # 检查必要命令
    check_command curl
    check_command wget
    check_command tar
    
    # 检查磁盘空间
    local disk_space=$(df -h /usr/local | awk 'NR==2 {print $4}')
    log_info "可用磁盘空间: $disk_space"
    
    # 安装JDK 1.8
    if ! install_jdk "8" "jdk8"; then
        log_warning "JDK 1.8 安装失败，跳过"
        log_info "建议: 可以尝试手动下载或检查网络连接"
    fi

    # 安装JDK 17
    if ! install_jdk "17" "jdk17"; then
        log_warning "JDK 17 安装失败，跳过"
        log_info "建议: 可以尝试手动下载或检查网络连接"
    fi
    
    # 安装JDK 25  
    if ! install_jdk "25" "jdk25"; then
        log_warning "JDK 25 安装失败，跳过"
        log_info "建议: 可以尝试手动下载或检查网络连接"
    fi
    
    # 显示安装结果
    show_installed_jdks
    
    # 检查是否至少安装了一个JDK
    if [ ! -L "/usr/lib64/jvm/jdk17" ] && [ ! -L "/usr/lib64/jvm/jdk25" ]; then
        log_error "所有JDK安装都失败了！"
        log_info "请检查以下内容:"
        log_info "1. 网络连接是否正常"
        log_info "2. 是否有足够的磁盘空间"
        log_info "3. 是否有sudo权限"
        log_info "4. 镜像站是否可用: https://mirrors.tuna.tsinghua.edu.cn/Adoptium/"
        exit 1
    fi
    
    log_success "JDK安装过程完成"
    
    # 配置JDK环境变量
    echo ""
    log_info "配置JDK环境变量..."
    
    # 检查是否安装了JDK 25，如果安装了则使用JDK 25作为默认，否则使用JDK 17
    local default_jdk="jdk17"
    if [ -L "/usr/lib64/jvm/jdk25" ]; then
        default_jdk="jdk25"
    fi
    
    # 在/etc/profile中配置JDK环境变量
    # 先移除任何现有的JDK环境变量配置
    log_info "移除现有的JDK环境变量配置..."
    sudo sed -i '/export JDK17=/d' /etc/profile
    sudo sed -i '/export JDK25=/d' /etc/profile
    sudo sed -i '/export JAVA_HOME=/d' /etc/profile
    sudo sed -i '/export PATH=.*JAVA_HOME/d' /etc/profile
    
    # 添加新的环境变量配置
    log_info "添加新的JDK环境变量配置..."
    sudo tee -a /etc/profile <<-'EOF'

# JDK环境变量配置
export JDK17=/usr/lib64/jvm/jdk17
export JDK25=/usr/lib64/jvm/jdk25
export JAVA_HOME=$JDK25
export PATH=$JAVA_HOME/bin:$PATH

EOF
    
    log_success "环境变量配置已更新到/etc/profile"
    
    # 刷新环境变量
    log_info "刷新环境变量..."
    source /etc/profile
    
    # 验证java版本
    log_info "验证Java版本..."
    java -version
    
    log_info "注意：如果vscode已经打开，需要关闭后再打开，为了刷新vscode环境变量缓存！"
    
    # 提示用户也可以手动设置
    echo ""
    log_info "或者你也可以手动将以下内容添加到你的 ~/.bashrc 或 ~/.bash_profile 文件中:"
    echo "export JAVA_HOME=/usr/lib64/jvm/$default_jdk"
    echo "export PATH=\$JAVA_HOME/bin:\$PATH"
    echo ""
    log_info "使用以下命令立即生效:"
    echo "export JAVA_HOME=/usr/lib64/jvm/$default_jdk"
    echo "export PATH=\$JAVA_HOME/bin:\$PATH"
    echo "source ~/.bashrc"
    
    log_success "JDK安装脚本执行完成！"
}

# 执行主函数
main "$@"
